// 1.  定义一个Promise构造函数，传入`excutor`执行器函数
function Promise(excutor) {
    // 2. 在构造函数内定义2个属性
    //    1. `this.PromiseState` 保存promise状态
    //    2. `this.PromiseResult`保存promise结果值
    this.PromiseState = "pending";
    this.PromiseResult = undefined;

    // 在对象上添加一个保存（resolve、reject）回调函数的数组 - this.callBacks
    this.callBacks = [];

    // 3. 定义resolve、reject函数
    //    1. 在resolve函数内修改`this.PromiseState` 为`fulfilled`，`this.PromiseResult`为value
    //    2. 在reject函数内修改`this.PromiseState`为 `rejected`,`this.PromiseResult` 为 reason
    let resolve = (value) => {
        //判断状态是否不为pending，非"pending"状态阻止代码向下执行
        if (this.PromiseState !== "pending") return;

        this.PromiseState = 'fulfilled';
        this.PromiseResult = value;
        // 判断callBacks是否有长度
        // 如果有 - 遍历数组并执行当中的每一个resolve函数
        if (this.callBacks.length) {
            this.callBacks.forEach(item => {
                item.resolve(value);
            })
        }
    }
    let reject = (reason) => {
        //判断状态是否不为pending，非"pending"状态阻止代码向下执行
        if (this.PromiseState !== "pending") return;

        this.PromiseState = 'rejected';
        this.PromiseResult = reason;
        // 判断callBacks是否有长度
        // 如果有 - 遍历数组并执行当中的每一个resolve函数
        if (this.callBacks.length) {
            this.callBacks.forEach(item => {
                item.reject(reason);
            })
        }
    }

    // 4. 调用`excutor`函数并传入resolve、reject函数
    // 5. try捕获执行`excutor`函数时抛出错误
    //    1. catch 内调用reject函数并传入err参数
    try {
        excutor(resolve, reject);
    } catch (err) {
        reject(err)
    }
}

// then方法
Promise.prototype.then = function (onResolve, onReject) {

    //设置onResolove和 onReject 默认函数体
    if (typeof onResolve !== "function") {
        onResolve = v => v;
    }

    if (typeof onReject !== "function") {
        onReject = (rea) => { throw rea };
    }

    return new Promise((resolve, reject) => {

        // 封装一个处理返回结果的函数，传入函数名
        let handle = (fnName) => {
            setTimeout(() => {
                try {
                    let res = fnName(this.PromiseResult);
                    if (res instanceof Promise) {
                        res.then(val => {
                            resolve(val)
                        }, rea => {
                            reject(rea)
                        });
                    } else {
                        resolve(res);
                    }
                } catch (error) {
                    reject(error);
                }
            });
        }

        // 同步操作
        if (this.PromiseState === "fulfilled") {
            // 替换函数调用
            handle(onResolve)
        }
        if (this.PromiseState === 'rejected') {
            handle(onReject)
        }

        // 添加异步操作 - 当对象状态为"pending"时
        // 先将所有的then方法内的回调存入callBacks数组里-等到后续调用
        if (this.PromiseState === "pending") {
            this.callBacks.push({
                resolve: () => {
                    handle(onResolve)
                },
                reject: () => {
                    handle(onReject)
                }
            });
        }
    })
}


//catch方法实现 - 调用 then方法 只传onReject回调
Promise.prototype.catch = function (onReject) {
    return this.then(undefined, onReject);
}

// 定义 函数方法 resolve
// 快速生成一个成功的pormise对象
Promise.resolve = function (val) {
    return new Promise((resolve, reject) => {
        // 判断参数是否是promise对象
        if (val instanceof Promise) {
            val.then((val) => {
                resolve(val)
            }, rea => {
                reject(rea)
            });
        } else {
            resolve(val);
        }
    })
}

// 新： 定义一个reject 函数方法，
// 快速生成一个失败的promise对象
Promise.reject = function (val) {
    return new Promise((resolve, reject) => {
        reject(val)
    });
}

